package com.danicsoft.daide.historian;

import java.util.ArrayList;
import java.util.List;

/**
 * The data that a <code>Historian</code> generates. A textbook is responsible
 * for tracking all messages sent to a historian. Any number of historians can
 * log to this textbook.
 * 
 * @author Daniel Yule (daniel.yule@gmail.com)
 * @version 1.0
 */
public abstract class Textbook {
	/**
	 * A list of messages that have been logged.
	 */
	private List<Entry> messages = new ArrayList<Entry>();

	/**
	 * The lowest level of importance that we will log.
	 */
	private int importanceLevel;

	/**
	 * A textbook that outputs to tehe console.
	 */
	private static Textbook consoleTextbook = new Textbook(0) {

		/**
		 * @param actor
		 * @param message
		 * @param importance
		 * @see com.danicsoft.daide.historian.Textbook#outputMessage(java.lang.Object,
		 *      java.lang.String, int)
		 */
		@Override
		protected void outputMessage(Object actor, String message, int importance) {
			System.out.println(actor.toString() + ":> " + message);
		}

	};

	/**
	 * Log that a message has been received
	 * 
	 * @param actor
	 *        The object that is the source of the message. This object's
	 *        toString method may be used for display.
	 * @param message
	 *        The message that has been generated.
	 * @param importance
	 *        The importance of this message. Any messages below the
	 *        importanceLevel of this Textbook will not be output.
	 */
	public void logMessage(Object actor, String message, int importance) {
		if (importance >= importanceLevel) {
			outputMessage(actor, message, importance);
		}
		messages.add(new Entry(actor, message, importance));
	}

	/**
	 * Output the given message.
	 * 
	 * @param actor
	 *        The object that is the source of the message. This object's
	 *        toString method may be used for display.
	 * @param message
	 *        The message that has been generated.
	 * @param importance
	 *        The importance of this message. Any messages below the
	 *        importanceLevel of this Textbook will not be output.
	 */
	protected abstract void outputMessage(Object actor, String message, int importance);

	/**
	 * Construct a new Textbook with the given importance level.
	 * 
	 * @param importanceLevel
	 *        The lowest level of importance that messages will be printed with.
	 */
	public Textbook(int importanceLevel) {
		this.importanceLevel = importanceLevel;
	}

	/**
	 * Gets a textbook that outputs to the command line. Its default
	 * importanceLevel is 0.
	 * 
	 * @return A console outputting textbook.
	 */
	public static Textbook getConsoleTextbook() {
		return consoleTextbook;
	}

	/**
	 * An entry in the textbook. It contains information about the message, who
	 * generated the message and how important the message was.
	 * 
	 * @author Daniel Yule (daniel.yule@gmail.com)
	 * @version 1.0
	 */
	private class Entry {
		/**
		 * The object responsible for this message.
		 */
		public Object actor;

		/**
		 * A message that has been logged.
		 */
		public String message;

		/**
		 * The importance of this message
		 */
		public int importance;

		/**
		 * Contruct a new Entry from the data given
		 * 
		 * @param actor
		 *        The actor.
		 * @param message
		 *        The message.
		 * @param importance
		 *        The importance.
		 * @see #actor
		 * @see #message
		 * @see #importance
		 */
		public Entry(Object actor, String message, int importance) {
			this.actor = actor;
			this.message = message;
			this.importance = importance;

		}
	}
}
